package utils

import (
	"github.com/Esword618/unioffice/color"
	"github.com/Esword618/unioffice/common"
	"github.com/Esword618/unioffice/document"
	"github.com/Esword618/unioffice/schema/soo/wml"
	"strconv"
	"strings"
	"ubt-aio-service/app/pkg/conf"
	"ubt-aio-service/app/pkg/logger"
)

// ExpWord 导出Word文档，并返回下载地址
func ExpWord(newName string, data map[string]any) string {
	tmplPath := conf.Cfg.AppConf.ExprPath

	// 加载Word文档模板
	tmplFile, err := document.Open(tmplPath)
	if err != nil {
		logger.Error("打开模板文件失败。" + err.Error())
		return ""
	}

	para := tmplFile.AddParagraph()
	run := para.AddRun()
	run.AddText(data["title"].(string))
	run.Properties().SetBold(true)
	run.Properties().SetSize(20)
	para.Properties().SetAlignment(wml.ST_JcCenter)

	para = tmplFile.AddParagraph()
	run = para.AddRun()
	run.AddText("答题时长：" + strconv.FormatInt(data["examTime"].(int64), 10) + "分钟    总分：" + strconv.FormatInt(data["score"].(int64), 10) + "分")
	para.Properties().SetAlignment(wml.ST_JcCenter)

	para = tmplFile.AddParagraph()
	run = para.AddRun()
	run.AddText("单位名称：" + data["deptName"].(string) + "    姓名：" + data["realName"].(string) + "    工号：" + data["workNo"].(string) + "    得分：" + data["myScore"].(string) + "分")
	para.Properties().SetAlignment(wml.ST_JcCenter)

	tmplFile.AddParagraph()

	// 插入题目
	for index, qst := range data["qstList"].([]map[string]any) {
		if qst["kind"].(int64) == 6 {
			para = tmplFile.AddParagraph()
			para.AddRun().AddText(strconv.FormatInt(int64(index+1), 10) + ". " + qst["title"].(string))

			// 插入图片
			insertImage(tmplFile, qst["fileUrls"].(string))

			for idx, opt := range qst["optList"].([]map[string]any) {
				para = tmplFile.AddParagraph()
				para.AddRun().AddText(strconv.FormatInt(int64(index+1), 10) + "." + strconv.FormatInt(int64(idx+1), 10) + ".1. 风险点描述")
				if opt["fxd"] != nil {
					para = tmplFile.AddParagraph()
					para.AddRun().AddText(opt["fxd"].(string))
					tmplFile.AddParagraph()
				} else {
					tmplFile.AddParagraph()
					tmplFile.AddParagraph()
					tmplFile.AddParagraph()
				}
				para = tmplFile.AddParagraph()
				para.AddRun().AddText(strconv.FormatInt(int64(index+1), 10) + "." + strconv.FormatInt(int64(idx+1), 10) + ".2. 事故类型")
				if opt["sglx"] != nil {
					para = tmplFile.AddParagraph()
					para.AddRun().AddText(opt["sglx"].(string))
					tmplFile.AddParagraph()
				} else {
					tmplFile.AddParagraph()
					tmplFile.AddParagraph()
					tmplFile.AddParagraph()
				}
				para = tmplFile.AddParagraph()
				para.AddRun().AddText(strconv.FormatInt(int64(index+1), 10) + "." + strconv.FormatInt(int64(idx+1), 10) + ".3. 管控措施")
				if opt["ffcs"] != nil {
					para = tmplFile.AddParagraph()
					para.AddRun().AddText(opt["ffcs"].(string))
					tmplFile.AddParagraph()
				} else {
					tmplFile.AddParagraph()
					tmplFile.AddParagraph()
					tmplFile.AddParagraph()
				}
			}
		} else {
			para = tmplFile.AddParagraph()
			para.AddRun().AddText(strconv.FormatInt(int64(index+1), 10) + ". " + qst["title"].(string) + " (" + qst["keywords"].(string) + ")")

			for _, opt := range qst["optList"].([]map[string]any) {
				para = tmplFile.AddParagraph()
				answer := opt["optNo"].(string) + "." + opt["optName"].(string)
				run = para.AddRun()
				if opt["myAnswer"] != nil && strings.Contains(opt["myAnswer"].(string), opt["optId"].(string)) {
					run.Properties().SetBold(true)
					run.Properties().SetColor(color.RGB(64, 158, 255))
				}
				run.AddText(answer)
			}
			tmplFile.AddParagraph()
		}
	}

	idx := strings.Index(tmplPath, "exam_tmpl.docx")
	newPath := conf.Cfg.AppConf.ExprPath[:idx] + "file/" + newName
	// 保存更新后的文档
	err = tmplFile.SaveToFile(newPath)
	if err != nil {
		logger.Error("导出的文件保存失败。" + err.Error())
	}

	return newPath
}

// replaceTags 替换文档中的标签
func replaceTags(doc *document.Document, tags map[string]string) {
	for _, para := range doc.Paragraphs() {
		for _, run := range para.Runs() {
			for key, value := range tags {
				run.AddText(strings.ReplaceAll(run.Text(), key, value))
			}
		}
	}
}

// insertImage 在指定标签处插入图片
func insertImage(doc *document.Document, imgUrl string) {
	idx := strings.Index(imgUrl, "/file")
	realPath := conf.Cfg.AppConf.FilePath + imgUrl[idx:]
	img, err := common.ImageFromFile(realPath)
	if err != nil {
		logger.Error("图片加载失败。" + err.Error())
		return
	}
	inline, err := doc.AddImage(img)
	if err != nil {
		logger.Error("图片插入失败。" + err.Error())
		return
	}
	para := doc.AddParagraph()
	run := para.AddRun()
	_, err = run.AddDrawingInline(inline)
	if err != nil {
		logger.Error("图片插入失败。" + err.Error())
		return
	}
}
